﻿// <file>
//     <copyright see="prj:///doc/copyright.txt"/>
//     <license see="prj:///doc/license.txt"/>
//     <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
//     <version>$Revision: 915 $</version>
// </file>

using System;
using System.Collections.Generic;

namespace ICSharpCode.TextEditor.Document
{
	/// <summary>
	/// A simple folding strategy which calculates the folding level
	/// using the indent level of the line.
	/// </summary>
	public class IndentFoldingStrategy : IFoldingStrategy
	{
        public int GetLevel(IDocument document, int offset)
        {
            int level = 0;
            int spaces = 0;
            for (int i = offset; i < document.TextLength; ++i)
            {
                char c = document.GetCharAt(i);
                if (c == '\t' || (c == ' ' && ++spaces == 4))
                {
                    spaces = 0;
                    ++level;
                }
                else
                {
                    break;
                }
            }
            return level;
        }

        public List<FoldMarker> GenerateFoldMarkers(IDocument document)
        {
            List<FoldMarker> list = new List<FoldMarker>();

            Stack<int> startLines = new Stack<int>();

            // Create foldmarkers for the whole document, enumerate through every line.
            for (int i = 0; i < document.TotalNumberOfLines; i++)
            {
                var seg = document.GetLineSegment(i);
                int offs, end = document.TextLength;
                char c;
                for (offs = seg.Offset; offs < end && ((c = document.GetCharAt(offs)) == ' ' || c == '\t'); offs++)
                {
                    //offs 增加
                }
                if (offs == end)
                    break;
                int spaceCount = offs - seg.Offset;

                // now offs points to the first non-whitespace char on the line

                int start = 0;               
                char dott = document.GetCharAt(offs);
                string text = document.GetText(offs, seg.Length - spaceCount);

                if (!string.IsNullOrEmpty(text))
                {
                    switch (dott)
                    {
                        case '#':

                            if (text.StartsWith("#region"))
                                startLines.Push(i);
                            if (text.StartsWith("#endregion") && startLines.Count > 0)
                            {
                                // Add a new FoldMarker to the list.
                                start = startLines.Pop();
                                list.Add(new FoldMarker(document, start,
                                    document.GetLineSegment(start).Length,
                                    i, spaceCount + "#endregion".Length));
                            }

                            break;

                        case '/':

                            if (text.StartsWith("/// <summary>"))
                                startLines.Push(i);
                            if (text.StartsWith("/// </summary>") && startLines.Count > 0)
                            {
                                // Add a new FoldMarker to the list.
                                start = startLines.Pop();
                                list.Add(new FoldMarker(document, start,
                                    document.GetLineSegment(start).Length,
                                    i, spaceCount + "/// </summary>".Length));
                            }

                            break;

                        case '{':
                        case '}':

                            text = document.GetText(offs, seg.Length - spaceCount);
                            if (text.StartsWith("{"))
                                startLines.Push(i);
                            if (text.StartsWith("}") && startLines.Count > 0)
                            {
                                // Add a new FoldMarker to the list.
                                start = startLines.Pop() - 1;
                                list.Add(new FoldMarker(document, start,
                                    document.GetLineSegment(start).Length,
                                    i, spaceCount + "}".Length));
                            }

                            break;
                        
                    }

                }


            }

            return list;
        }
		
		public List<FoldMarker> GenerateFoldMarkers(IDocument document, string fileName, object parseInformation)
		{
            List<FoldMarker> list = new List<FoldMarker>();

            Stack<int> startLines = new Stack<int>();

            // Create foldmarkers for the whole document, enumerate through every line.
            for (int i = 0; i < document.TotalNumberOfLines; i++)
            {
                var seg = document.GetLineSegment(i);
                int offs, end = document.TextLength;
                char c;
                for (offs = seg.Offset; offs < end && ((c = document.GetCharAt(offs)) == ' ' || c == '\t'); offs++)
                {
                    //offs 增加
                }
                if (offs == end)
                    break;
                int spaceCount = offs - seg.Offset;

                // now offs points to the first non-whitespace char on the line

                int start = 0;
                char dott = document.GetCharAt(offs);
                string text = document.GetText(offs, seg.Length - spaceCount);

                if (!string.IsNullOrEmpty(text))
                {
                    switch (dott)
                    {
                        case '#':

                            if (text.StartsWith("#region"))
                                startLines.Push(i);
                            if (text.StartsWith("#endregion") && startLines.Count > 0)
                            {
                                // Add a new FoldMarker to the list.
                                start = startLines.Pop();
                                list.Add(new FoldMarker(document, start,
                                    document.GetLineSegment(start).Length,
                                    i, spaceCount + "#endregion".Length));
                            }

                            break;

                        case '/':

                            if (text.StartsWith("/// <summary>"))
                                startLines.Push(i);
                            if (text.StartsWith("/// </summary>") && startLines.Count > 0)
                            {
                                // Add a new FoldMarker to the list.
                                start = startLines.Pop();
                                list.Add(new FoldMarker(document, start,
                                    document.GetLineSegment(start).Length,
                                    i, spaceCount + "/// </summary>".Length));
                            }

                            break;

                        case '{':
                        case '}':

                            text = document.GetText(offs, seg.Length - spaceCount);
                            if (text.StartsWith("{"))
                                startLines.Push(i);
                            if (text.StartsWith("}") && startLines.Count > 0)
                            {
                                // Add a new FoldMarker to the list.
                                start = startLines.Pop() - 1;
                                list.Add(new FoldMarker(document, start,
                                    document.GetLineSegment(start).Length,
                                    i, spaceCount + "}".Length));
                            }

                            break;

                    }

                }


            }

            return list;
		}

	}
}
